package com.medical.data.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.medical.data.component.LoginUserThreadLocal;
import com.medical.data.config.RedisCache;
import com.medical.data.constEnum.CommonEnum;
import com.medical.data.constEnum.FormRedisKeyConstants;
import com.medical.data.domain.*;
import com.medical.data.exception.MyException;
import com.medical.data.mapper.FormDataMapper;
import com.medical.data.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medical.data.utils.AddressUtils;
import com.medical.data.utils.HttpUtils;
import com.medical.data.utils.ResultCode;
import com.medical.data.vo.*;
import lombok.Data;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 * 表单数据 服务实现类
 * </p>
 *
 * @author cj
 * @since 2024-01-23
 */
@Service
public class FormDataServiceImpl extends ServiceImpl<FormDataMapper, FormData> implements FormDataService {

    @Autowired
    private TokenSerivce tokenSerivce;

    @Autowired
    private FormItemService formItemService;


    @Autowired
    private RedisCache redisCache;

    @Autowired
    private PatientService patientService;


    @Autowired
    private PatientTemplateService patientTemplateService;


    @Autowired
    private TemplateFormService templateFormService;

    @Autowired
    private UserPermissionService userPermissionService;

    @Override
    @Transactional(rollbackFor = MyException.class)
    public void addFormData(FormData formData, HttpServletRequest request) {
        userPermissionService.getDataPermission(formData.getProjectId());

//        if (formData.getStatus()) {
//            throw new MyException(ResultCode.ERROR.getCode(), "表单已提交,不能重复提交或保存");
//        }
        LambdaQueryWrapper<FormData> wrapper4 = new LambdaQueryWrapper<>();
        wrapper4.eq(FormData::getPatientId, formData.getPatientId())
                .eq(FormData::getFormId, formData.getFormId())
                .eq(FormData::getProjectId, formData.getFormId());
        FormData formData2 = this.baseMapper.selectOne(wrapper4);
        if (ObjectUtils.isNotEmpty(formData2)) {
            if (!formData.getStatus()&&formData2.getStatus()) {
                throw new MyException(ResultCode.ERROR.getCode(), "表单已提交,不能重复提交或保存");
            }
        }
        templateFormService.getFormByFormId(formData.getFormId(), formData.getNodeId());
        if (StringUtils.isBlank(formData.getProjectId()))
            throw new MyException(ResultCode.ERROR.getCode(), "项目不可为空");
        User user = tokenSerivce.getUser();
        formData.setDoctorName(user.getNickName());
        formData.setSubmitRequestIp(HttpUtils.getIpAddr(request));
        String formId = formData.getFormId();
        formData.setSubmitAddress(AddressUtils.getRealAddressByIP(formData.getSubmitRequestIp()));
        formData.setSerialNumber(redisCache.incr(StrUtil.format(FormRedisKeyConstants.FORM_RESULT_NUMBER, formId), CommonEnum.NUMBERONE.getNumber()));
        //在这里判断是否为更新数据和添加数据
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getNodeId, formData.getNodeId())
                .eq(FormData::getFormId, formData.getFormId())
                .eq(FormData::getPatientId, formData.getPatientId());
        FormData formData1 = this.baseMapper.selectOne(wrapper);
        if (ObjectUtil.isNotEmpty(formData1)) {
            if (formData1.getStatus()) {
                throw new MyException(ResultCode.ERROR.getCode(), "此表单已填写完成，不能重复填写");
            } else {
                int update = this.baseMapper.update(formData, wrapper);
                if (update < 1) {
                    throw new MyException(ResultCode.ERROR.getCode(), "更新填写数据失败");
                }
            }
        } else {
            int insert = baseMapper.insert(formData);
            if (insert < 1)
                throw new MyException(ResultCode.ERROR.getCode(), "新增数据失败");
        }
        //当新增数据完成以后，将表单的状态改为已完成
        if (formData.getStatus()) {
            /*formTemplateService.updateById(new FormTemplate().setId(formId).setStatus(true));*/
            //更新患者与节点中间表
            patientTemplateService.updatePatientTemplate(formData.getProjectId(), formData.getPatientId());
        }
    }

    /*    @Override
        @Transactional(rollbackFor = MyException.class)
        public Map<String,Object> saveFormData(FormData formData, HttpServletRequest request) {
            if (StringUtils.isBlank(formData.getProjectId()))
                throw new MyException(ResultCode.ERROR.getCode(), "项目不可为空");
            User user = tokenSerivce.getUser();
            formData.setDoctorName(user.getNickName());
            formData.setSubmitRequestIp(HttpUtils.getIpAddr(request));
            Map<String,Object> map = new HashMap<>();
            String formId = formData.getFormId();
            formData.setSubmitAddress(AddressUtils.getRealAddressByIP(formData.getSubmitRequestIp()));
            formData.setSerialNumber(redisCache.incr(StrUtil.format(FormRedisKeyConstants.FORM_RESULT_NUMBER, formId), CommonEnum.NUMBERONE.getNumber()));
            formData.setStatus(false);
            int insert = baseMapper.insert(formData);
            if (insert<1)
                throw new MyException(ResultCode.ERROR.getCode(), "新增数据失败");
            map.put("id", formData.getId());
            //当保存数据完成以后，将表单的状态改为未完成
            formTemplateService.updateById(new FormTemplate().setId(formId).setStatus(false));
            //更新患者与节点中间表
            patientTemplateService.updatePatientTemplate(formData.getProjectId(),formData.getPatientId());
            return map;
        }*/
    @Override
    public Map<String, Object> getFormData(QueryFormDataVo queryFormDataVo, HttpServletRequest request) {
        Integer current = CommonEnum.CURRENT.getValue();
        Integer limit = CommonEnum.LIMIT.getValue();
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getFormId, queryFormDataVo.getFormId());
        //做分页
        if (!ObjectUtils.isEmpty(queryFormDataVo)) {
            if (!ObjectUtils.isEmpty(queryFormDataVo.getBeginTime())) {
                wrapper.ge(FormData::getCreateTime, queryFormDataVo.getBeginTime());
            }
            if (!ObjectUtils.isEmpty(queryFormDataVo.getEndTime())) {
                wrapper.le(FormData::getCreateTime, queryFormDataVo.getEndTime());
            }
            if (!ObjectUtils.isEmpty(queryFormDataVo.getCurrent())) {
                current = queryFormDataVo.getCurrent();
            }
            if (!ObjectUtils.isEmpty(queryFormDataVo.getLimit())) {
                limit = queryFormDataVo.getLimit();
            }
        }
        wrapper.orderByDesc(FormData::getCreateTime);
        Page<FormData> page = new Page<>(current, limit);
        baseMapper.selectPage(page, wrapper);
        List<FormData> formDatas = page.getRecords();
        Map<String, Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("current", current);
        map.put("limit", limit);
        map.put("formDatas", formDatas);
        return map;
    }

    @Override
    public Map<String, Object> getFormDataDetail(String dataId) {
        Map<String, Object> result = new HashMap<>();
        FormData formData = baseMapper.selectById(dataId);
        List<FormFieldVO> formItem = formItemService.listFormFields(formData.getFormId());

        // 表单字段
        result.put("formFields", formItem);
        // 表单填写数据
        if (ObjectUtil.isNotNull(formData)) {
            Map<String, Object> originalData = formData.getOriginalDataJson();
/*            formData.setOriginalData(null);
            originalData.putAll(BeanUtil.beanToMap(formData, false, true));*/
            result.put("formData", originalData);
        }
        return result;
    }

    @Override
    public List<FormData> getFormDataStatuByIds(List<String> ids, String patientId, String projectId) {
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(FormData::getFormId, ids);
        if (StringUtils.isNotBlank(patientId))
            wrapper.eq(FormData::getPatientId, patientId);
        if (StringUtils.isNotBlank(projectId))
            wrapper.eq(FormData::getProjectId, projectId);
        List<FormData> formData = baseMapper.selectList(wrapper);
        return formData;
    }

    @Override
    public Map<String, Object> getFormDataByPatient(GetFormDataVo getFormDataVo) {
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getNodeId, getFormDataVo.getNodeId())
                .eq(FormData::getFormId, getFormDataVo.getFormId())
                .eq(FormData::getPatientId, getFormDataVo.getPatientId());

        FormData formData = this.baseMapper.selectOne(wrapper);
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> originalData = new HashMap<>();
        Boolean status = false;
        if (ObjectUtil.isNotEmpty(formData)) {
            originalData = formData.getOriginalDataJson();
            status = formData.getStatus();
        } else {
            originalData = null;
            status = false;
        }
        result.put("status", status);
        result.put("data", originalData);
        return result;
    }

    @Override
    public List<LastDataVo> passDataNumber() {
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
        Date currentDate = new Date();
        Calendar calendar = Calendar.getInstance();
        int day = 6;

        List<LastDataVo> resultList = new ArrayList<>();
        for (int i = day; i >= 0; i--) {
            long timeInMillis = currentDate.getTime() - i * 24 * 60 * 60 * 1000; // 计算新的时间
            Date time = new Date(timeInMillis); // 创建新的开始时间
            calendar.setTime(time);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date startTime = calendar.getTime();
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            Date endTime = calendar.getTime(); // 创建新的结束时间

            LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
            wrapper.between(FormData::getCreateTime, startTime, endTime);
            List<FormData> formData = this.baseMapper.selectList(wrapper);
            resultList.add(new LastDataVo(sdf.format(startTime), formData.size()));
        }
        return resultList;
    }

    @Override
    public void deleteDataById(String patientId) {
        userPermissionService.getDataPermission(patientService.getProjectIdByPatientId(patientId));
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getPatientId, patientId);
        int delete = this.baseMapper.delete(wrapper);
        if (delete < 0) {
            throw new MyException(ResultCode.ERROR.getCode(), "删除患者填写数据失败");
        }
    }

    @Override
    public void deleteDateByNodeId(String nodeId) {
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getNodeId, nodeId);
        int delete = this.baseMapper.delete(wrapper);
        if (delete < 0) {
            throw new MyException(ResultCode.ERROR.getCode(), "删除患者填写数据失败");
        }
    }

    @Override
    public void deleteDataByFormId(String formId) {
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormData::getFormId, formId);
        List<FormData> formData = this.baseMapper.selectList(wrapper);
        for (FormData formData1 : formData) {
            userPermissionService.getDataPermission(formData1.getProjectId());
        }
        if (formData.size() != 0) {
            int delete = this.baseMapper.delete(wrapper);
            if (delete < 0) {
                throw new MyException(ResultCode.ERROR.getCode(), "删除患者填写数据失败");
            }
        }

    }

    @Override
    public List<Map<String, String>> exportFormData(ExportVo exportVo) {
        for (String patientId : exportVo.getPatientIds()) {
            userPermissionService.getDataPermission(patientService.getProjectIdByPatientId(patientId));
        }
        List<Map<String, String>> returnList = new ArrayList<>();
        List<String> patientIds = exportVo.getPatientIds();
        List<String> formItemIds = exportVo.getFormItemIds();
        String formId = exportVo.getFormId();
        for (String patientId : patientIds) {
            LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FormData::getFormId, formId)
                    .eq(FormData::getPatientId, patientId);
            FormData formData = this.baseMapper.selectOne(wrapper);
            Patient patient = patientService.getPatientById(patientId);
            if (formData != null) {
                JSONObject originalDataJson = formData.getOriginalDataJson();
                Map<String, String> valueMap = new HashMap<>();
                String patientCode1 = "患者住院号";
                String patientCode2 = patient.getRecordNumber();
                valueMap.put(patientCode1, patientCode2);
                String patientName1 = "患者姓名";
                String patientName2 = patient.getPatientName();
                valueMap.put(patientName1, patientName2);
                for (String formItemId : formItemIds) {
                    String label = formItemService.getLabelByFormId(formItemId); // 假设这是获取 label 的方法
                    String value = originalDataJson.getString(formItemId);
                    valueMap.put(label, value);
                }
                returnList.add(valueMap);
            }

        }
        return returnList;
    }

    @Override
    public int getFormDataNumber() {
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        return this.baseMapper.selectList(wrapper).size();
    }

    @Override
    public int getTodayFormDataNumber() {
        LocalDate today = LocalDate.now();
        LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply("DATE(create_time) = DATE({0})", today); // 使用DATE()函数比较日期部分;
        return this.baseMapper.selectList(wrapper).size();
    }


/*    @Override
    public void exportFormData() {
            String filename = "D:\\study\\excel\\user1.xlsx";

            // 向Excel中写入数据 也可以通过 head(Class<?>) 指定数据模板
            EasyExcel.write(filename, User.class)
                    .sheet("用户信息")
                    .doWrite(getUserData());
    }

    private List<User> getUserData() {
        List<User> users = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            User user = User.builder()
                    .userId(i)
                    .userName("admin" + i)
                    .gender(i % 2 == 0 ? "男" : "女")
                    .salary(i * 1000.00)
                    .hireDate(new Date())
                    .build();
            users.add(user);
        }
        return users;
    }*/
}
